home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 February: Tool Chest / Dev.CD Feb 99 TC.toast / Tool Chest / Interapplication Communication / ScriptableStuffItEngine / Project / SSE_AppleEventHandler.cp < prev    next >
Encoding:
Text File  |  1998-12-02  |  9.6 KB  |  459 lines  |  [TEXT/CWIE]

  1. /*
  2.     You may incorporate this Apple sample source code into your program(s) without
  3.     restriction. This Apple sample source code has been provided "AS IS" and the
  4.     responsibility for its operation is yours. You are not permitted to redistribute
  5.     this Apple sample source code as "Apple sample source code" after having made
  6.     changes. If you're going to re-distribute the source, we require that you make
  7.     it clear in the source that the code was descended from Apple sample source
  8.     code, but that you've made changes.
  9. */
  10.  
  11. #include "ScriptableStuffItEngine.h"    // app
  12. #include "StuffItEngineLib.h"            // Aladdin
  13. #include "FullPath.h"                    // MoreFiles
  14.  
  15. #include <Aliases.h>
  16. #include <PLStringFuncs.h>
  17. #include <Errors.h>
  18.  
  19. static pascal OSErr RespondToCoreEvent
  20.     (const AppleEvent *, AppleEvent *, AEEventID eventID)
  21. {
  22.     OSErr err = errAEEventNotHandled;
  23.  
  24.     switch (eventID)
  25.     {
  26.         case kAEQuitApplication :
  27.  
  28.             gQuitting = true;
  29.             err = noErr;
  30.             break;
  31.     }
  32.  
  33.     return err;
  34. }
  35.  
  36. static pascal OSErr GetTextParameter (const AppleEvent *event, AEKeyword keyWord, UInt8 **pp)
  37. {
  38.     OSErr err = noErr;
  39.  
  40.     DescType    actualType;
  41.     Size        dataSize;
  42.  
  43.     if (!(err = AEGetParamPtr (event,keyWord,typeChar,&actualType,nil,0,&dataSize)))
  44.     {
  45.         UInt8 *dataP = (UInt8 *) ::NewPtr (dataSize);
  46.  
  47.         if (!dataP)
  48.             err = ::MemError ( );
  49.         else
  50.         {
  51.             Size actualSize;
  52.  
  53.             if (!(err = ::AEGetParamPtr (event,keyWord,typeChar,&actualType,dataP,dataSize,&actualSize)))
  54.             {
  55.                 if (dataSize == actualSize)
  56.                     *pp = dataP;
  57.                 else
  58.                 {
  59.                     ::DebugStr ("\pFirst call to AEGetParamPtr lied about dataSize.");
  60.                     err = errAECorruptData;
  61.                 }
  62.             }
  63.  
  64.             if (err) ::DisposePtr (Ptr (dataP));
  65.         }
  66.     }
  67.  
  68.     return err;
  69. }
  70.  
  71. pascal OSErr GetOptionalTextParameter (const AppleEvent *event, AEKeyword keyWord, UInt8 **pp)
  72. {
  73.     OSErr err = GetTextParameter (event,keyWord,pp);
  74.  
  75.     if (err == errAEDescNotFound)
  76.     {
  77.         *pp = nil;
  78.         err = noErr;
  79.     }
  80.  
  81.     return err;
  82. }
  83.  
  84. pascal OSErr GetOptionalBoolean (const AppleEvent *ae, Boolean *b, AEKeyword keyWord)
  85. {
  86.     DescType    actualType;
  87.     Size        actualSize;
  88.     Boolean        oldB = *b;
  89.     OSErr        err = AEGetParamPtr (ae,keyWord,typeBoolean,&actualType,b,sizeof(*b),&actualSize);
  90.  
  91.     if (err == errAEDescNotFound)
  92.         { *b = oldB; err = noErr; }
  93.  
  94.     return err;
  95. }
  96.  
  97. #pragma mark -
  98.  
  99. #define kLowerCase        "abcdefghijklmnopqrstuvwxyz"
  100. #define kUpperCase        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  101. #define kNumerals        "0123456789"
  102. #define kPunctuation    "._-"
  103.  
  104. static pascal OSErr PrepareFilenameForUnix (const AppleEvent *event, AppleEvent *reply)
  105. {
  106.     OSErr err = noErr;
  107.  
  108.     UInt8 *dataP;
  109.  
  110.     if (!(err = ::GetTextParameter (event,keyDirectObject,&dataP)))
  111.     {
  112.         UInt32 dataSize = GetPtrSize (Ptr (dataP)), index = dataSize;
  113.  
  114.         while (index--)
  115.         {
  116.             // PLpos is my work-around for broken PLstrchr
  117.  
  118.             Str15 testStr = { 1, dataP [index] };
  119.  
  120.             if (!::PLpos (testStr, "\p" kLowerCase kUpperCase kNumerals kPunctuation))
  121.                 dataP [index] = '_';
  122.         }
  123.  
  124.         err = ::AEPutParamPtr (reply,keyDirectObject,typeChar,dataP,dataSize);
  125.  
  126.         ::DisposePtr ((Ptr) dataP);
  127.         if (!err) err = ::MemError ( );
  128.     }
  129.  
  130.     return err;
  131. }
  132.  
  133. static pascal OSErr DeleteFiles (const AppleEvent *event)
  134. {
  135.     OSErr err = noErr;
  136.  
  137.     AEDescList fileList;
  138.  
  139.     if (!(err = AEGetParamDesc (event,keyDirectObject,typeAEList,&fileList)))
  140.     {
  141.         OSErr err2 = noErr;
  142.  
  143.         long itemCount;
  144.  
  145.         if (!(err = AECountItems (&fileList,&itemCount)) && itemCount)
  146.         {
  147.             long index = 1;
  148.  
  149.             do
  150.             {
  151.                 FSSpec        deleteMe;
  152.                 AEKeyword    dontCareKeyword;
  153.                 DescType    actualType;
  154.                 Size        actualSize;
  155.  
  156.                 err = AEGetNthPtr (&fileList,index,typeFSS,&dontCareKeyword,&actualType,&deleteMe,sizeof(deleteMe),&actualSize);
  157.                 if (err) break;
  158.  
  159.                 if (actualType != typeFSS)
  160.                     err = paramErr;
  161.                 else if (actualSize < sizeof (deleteMe) - sizeof (deleteMe.name) + *(deleteMe.name) + 1)
  162.                     err = paramErr;
  163.                 else
  164.                     err = FSpDelete (&deleteMe);
  165.  
  166.                 if (err) break;
  167.             }
  168.             while (++index <= itemCount);
  169.         }
  170.  
  171.         err2 = AEDisposeDesc (&fileList);
  172.         if (!err) err = err2;
  173.     }
  174.  
  175.     return err;
  176. }
  177.  
  178. #pragma mark -
  179.  
  180. static pascal OSErr MakeArchiveSelfExtracting
  181.     (const AppleEvent *ae, AppleEvent *reply, long magicCookie)
  182. {
  183.     AEDesc aliasDesc;
  184.     OSErr err = AEGetParamDesc (ae,keyDirectObject,typeAlias,&aliasDesc);
  185.  
  186.     if (!err)
  187.     {
  188.         Boolean convertFileName = true;
  189.  
  190.         if (!(err = GetOptionalBoolean (ae,&convertFileName,keyConvertFileName)))
  191.         {
  192.             FSSpec        fss;
  193.             Boolean        wasChanged;
  194.  
  195.             if (!(err = ResolveAlias (nil,AliasHandle(aliasDesc.dataHandle),&fss,&wasChanged)))
  196.             if (!(err = ConvertSITtoSEA (magicCookie, &fss)))
  197.             {
  198.                 if (convertFileName)
  199.                 {
  200.                     ConstStr255Param dotSIT = "\p.sit";
  201.     
  202.                     if (*(fss.name) - *dotSIT + 1 == PLpos (dotSIT, fss.name))
  203.                     {
  204.                         Str31 newName;
  205.                         PLstrcpy (newName, fss.name);
  206.                         *newName -= *dotSIT;
  207.                         PLstrcat (newName, "\p.sea");
  208.  
  209.                         if (!(err = FSpRename (&fss,newName)))
  210.                         {
  211.                             PLstrcpy (fss.name, newName);
  212.                             err = UpdateAlias (nil,&fss,AliasHandle(aliasDesc.dataHandle),&wasChanged);
  213.                         }
  214.                     }
  215.                 }
  216.  
  217.                 if (!err)
  218.                     err = AEPutParamDesc (reply,keyDirectObject,&aliasDesc);
  219.             }
  220.         }
  221.  
  222.         OSErr err2 = AEDisposeDesc (&aliasDesc);
  223.         if (!err) err = err2;
  224.     }
  225.  
  226.     return err;
  227. }
  228.  
  229. static pascal OSErr HandleCountSegments
  230.     (const AppleEvent *ae, AppleEvent *reply, long magicCookie)
  231. {
  232.     AEDesc fssDesc;
  233.  
  234.     OSErr err = AEGetParamDesc (ae,keyDirectObject,typeFSS,&fssDesc);
  235.  
  236.     if (!err)
  237.     {
  238.         long        segSize;
  239.         DescType    actualType;
  240.         Size        actualSize;
  241.  
  242.         if (!(err = AEGetParamPtr
  243.             (ae,keySegmentSize,typeLongInteger,&actualType,&segSize,sizeof(segSize),&actualSize)))
  244.         {
  245.             HLockHi (fssDesc.dataHandle);
  246.  
  247.             FSSpecPtr targetFSS = FSSpecPtr (*(fssDesc.dataHandle));
  248.  
  249.             short numSegments;
  250.  
  251.             if (!(err = CountSegments (magicCookie,targetFSS,segSize,&numSegments)))
  252.                 err = AEPutParamPtr (reply,keyDirectObject,typeShortInteger,&numSegments,sizeof(numSegments));
  253.         }
  254.  
  255.         OSErr err2 = AEDisposeDesc (&fssDesc);
  256.         if (!err) err = err2;
  257.     }
  258.  
  259.     return err;
  260. }
  261.  
  262. static pascal OSErr EncodeIntoBinHex
  263.     (const AppleEvent *ae, long magicCookie)
  264. {
  265.     AEDesc sourceDesc;
  266.  
  267.     OSErr err = AEGetParamDesc (ae,keyDirectObject,typeFSS,&sourceDesc);
  268.  
  269.     if (!err)
  270.     {
  271.         OSErr err2;
  272.         AEDesc destDesc;
  273.  
  274.         if (!(err = AEGetParamDesc (ae,keyDestination,typeFSS,&destDesc)))
  275.         {
  276.             Boolean keepSource = true;
  277.  
  278.             if (!(err = GetOptionalBoolean (ae,&keepSource,keyKeepSource)))
  279.             {
  280.                 HLockHi (sourceDesc.dataHandle);
  281.                 HLockHi (destDesc.dataHandle);
  282.  
  283.                 FSSpecPtr    sourceFSS    = FSSpecPtr (*(sourceDesc.dataHandle)),
  284.                             destFSS        = FSSpecPtr (*(destDesc.dataHandle));
  285.  
  286.                 err = HQXEncodeFSSpec (magicCookie,sourceFSS,destFSS,
  287.                     !keepSource,false,kDefaultHQXCreator);
  288.  
  289.                 // there doesn't seem to be any way to return the file
  290.                 // that was actually created!
  291.             }
  292.  
  293.             err2 = AEDisposeDesc (&destDesc);
  294.             if (!err) err = err2;
  295.         }
  296.  
  297.         err2 = AEDisposeDesc (&sourceDesc);
  298.         if (!err) err = err2;
  299.     }
  300.  
  301.     return err;
  302. }
  303.  
  304. #pragma mark -
  305.  
  306. static pascal OSErr RespondToMiscFileHandlingEvent
  307.     (const AppleEvent *ae, AppleEvent *reply, AEEventID eventID)
  308. {
  309.     OSErr err = noErr;
  310.  
  311.     switch (eventID)
  312.     {
  313.         case kEventID_PrepareFilenameForUnix :
  314.         
  315.             err = PrepareFilenameForUnix (ae,reply);
  316.             break;
  317.  
  318.         case kEventID_Delete :
  319.  
  320.             err = DeleteFiles (ae);
  321.             break;
  322.  
  323.         case kEventID_Search :
  324.  
  325.             err = FindFiles (ae,reply);
  326.             break;
  327.  
  328.         default :
  329.  
  330.             err = errAEEventNotHandled;
  331.             break;
  332.     }
  333.  
  334.     return err;
  335. }
  336.  
  337. static pascal OSErr RespondToScriptableStuffItEngineEvent
  338.     (const AppleEvent *ae, AppleEvent *reply, AEEventID eventID)
  339. {
  340.     OSErr err = noErr;
  341.  
  342.     long magicCookie;
  343.  
  344.     if (!(err = OpenSITEngine (kUseExternalEngine, &magicCookie)))
  345.     {
  346.         short engineVersion = GetSITEngineVersion (magicCookie);
  347.  
  348.         if (engineVersion < kFirstSupportedEngine)
  349.         {
  350.             // reply that the engine is too old
  351.         }
  352.         else
  353.         {
  354.             static Boolean warnedAboutRegister;
  355.  
  356.             if (!warnedAboutRegister && !IsSITEngineRegistered (magicCookie))
  357.                 err = AEInteractWithUser (kNoTimeOut,nil,nil);
  358.  
  359.             if (!err)
  360.             {
  361.                 switch (eventID)
  362.                 {
  363.                     case kEventID_EncodeIntoBinHex :
  364.  
  365.                         err = EncodeIntoBinHex (ae,magicCookie);
  366.                         break;
  367.  
  368.                     case kEventID_Stuff :
  369.  
  370.                         err = Stuff (ae,reply,magicCookie);
  371.                         break;
  372.  
  373.                     case kEventID_CountSegments :
  374.  
  375.                         err = HandleCountSegments (ae,reply,magicCookie);
  376.                         break;
  377.  
  378.                     case kEventID_MakeArchiveSelfExtracting :
  379.  
  380.                         err = MakeArchiveSelfExtracting (ae,reply,magicCookie);
  381.                         break;
  382.  
  383.                     case kEventID_MakeSegments :
  384.  
  385.                         err = MakeSegments (ae,reply,magicCookie);
  386.                         break;
  387.  
  388.                     default :
  389.  
  390.                         err = errAEEventNotHandled;
  391.                         break;
  392.                 }
  393.             }
  394.  
  395.             warnedAboutRegister = true;
  396.         }
  397.  
  398.         CloseSITEngine (magicCookie);
  399.     }
  400.  
  401.     return err;
  402. }
  403.  
  404. #pragma mark -
  405.  
  406. pascal OSErr ScriptableStuffItAppleEventHandler
  407.     (const AppleEvent *ae, AppleEvent *reply, UInt32)
  408. {
  409.     AEEventClass    eventClass;
  410.     AEEventID        eventID;
  411.     DescType        actualType;
  412.     Size            actualSize;
  413.     OSErr            err;
  414.  
  415.     do
  416.     {
  417.         err = ::AEGetAttributePtr (ae, keyEventClassAttr, typeType, &actualType, (Ptr) &eventClass, sizeof (eventClass), &actualSize);    
  418.         if (err) break;
  419.         err = ::AEGetAttributePtr (ae, keyEventIDAttr, typeType, &actualType, (Ptr) &eventID, sizeof (eventID), &actualSize);
  420.         if (err) break;
  421.     }
  422.     while (false);
  423.  
  424.     if (!err)
  425.     {
  426.         switch (eventClass)
  427.         {
  428.             case kCoreEventClass :
  429.  
  430.                 err = RespondToCoreEvent (ae,reply,eventID);
  431.                 if (err == errAEEventNotHandled) err = noErr;
  432.                 break;
  433.  
  434.             case kEventClass_ScriptableStuffIt :
  435.  
  436.                 err = RespondToScriptableStuffItEngineEvent (ae,reply,eventID);
  437.                 break;
  438.  
  439.             case kEventClass_MiscFileHandling :
  440.  
  441.                 err = RespondToMiscFileHandlingEvent (ae,reply,eventID);
  442.                 break;
  443.  
  444.             default :
  445.  
  446.                 err = errAEEventNotHandled;
  447.                 break;
  448.         }
  449.  
  450.         if (err != errAEEventNotHandled && reply->dataHandle)
  451.             (void) AEPutParamPtr (reply,keyErrorNumber,typeShortInteger,&err,sizeof(err));
  452.     }
  453.  
  454.     if (err && err != errAEEventNotHandled)
  455.         err = noErr; // eat it; AppleEvent Manager won't do anything good with it
  456.  
  457.     return err;
  458. }
  459.